import { query } from '../config/db.js';
import logger from '../config/logger.js';
import cache from '../config/redis.js';
import axios from 'axios';

import dotenv from 'dotenv';

dotenv.config();

// 测试配置
const TEST_CLUB_NAME = '测试社团';
const TEST_CLUB_MEMBER_COUNT = 5; // 社团人数上限设为5
const TEST_STUDENT_COUNT = 10; // 模拟10个学生同时报名
const API_URL = 'http://localhost:3000/api/club_registrations/seckill';
const TEST_TOKEN = 'your_test_token'; // 替换为实际的测试token

// 准备测试数据
async function prepareTestData() {
  try {
    logger.info('准备测试数据...');

    // 创建测试社团
    await query('DELETE FROM clubs WHERE club_name = ?', [TEST_CLUB_NAME]);
    await query(
      'INSERT INTO clubs (club_name, member_count, location) VALUES (?, ?, ?)',
      [TEST_CLUB_NAME, TEST_CLUB_MEMBER_COUNT, '测试地点']
    );
    logger.info(`创建测试社团: ${TEST_CLUB_NAME}，人数上限: ${TEST_CLUB_MEMBER_COUNT}`);

    // 清空之前的测试报名记录
    await query('DELETE FROM club_registrations WHERE club_name = ?', [TEST_CLUB_NAME]);
    logger.info('清空之前的测试报名记录');

    // 清除相关缓存
    await cache.del(`club:${TEST_CLUB_NAME}:count`);
    await cache.del(`club:${TEST_CLUB_NAME}:limit`);
    for (let i = 1; i <= TEST_STUDENT_COUNT; i++) {
      await cache.del(`student:测试学生${i}:registration`);
    }
    logger.info('清除相关缓存');

    logger.info('测试数据准备完成');
  } catch (error) {
    logger.error('准备测试数据错误:', error);
    throw error;
  }
}

// 模拟学生报名
async function simulateStudentRegistration(studentId) {
  const studentName = `测试学生${studentId}`;
  try {
    const response = await axios.post(
      API_URL,
      {
        class_name: '测试班级',
        student_name: studentName,
        club_name: TEST_CLUB_NAME
      },
      {
        headers: {
          Authorization: `Bearer ${TEST_TOKEN}`
        }
      }
    );
    logger.info(`学生${studentName}报名成功:`, response.data.message);
    return { success: true, studentName };
  } catch (error) {
    const message = error.response?.data?.message || error.message;
    logger.info(`学生${studentName}报名失败:`, message);
    return { success: false, studentName, message };
  }
}

// 运行并发测试
async function runConcurrentTest() {
  try {
    logger.info(`开始并发测试: ${TEST_STUDENT_COUNT}个学生同时报名${TEST_CLUB_NAME}`);

    // 创建并发请求
    const promises = [];
    for (let i = 1; i <= TEST_STUDENT_COUNT; i++) {
      promises.push(simulateStudentRegistration(i));
    }

    // 等待所有请求完成
    const results = await Promise.all(promises);

    // 统计结果
    const successCount = results.filter(result => result.success).length;
    const failCount = results.filter(result => !result.success).length;

    logger.info(`测试结果: 成功${successCount}人，失败${failCount}人`);

    // 验证数据库中的记录数
    const dbResult = await query('SELECT COUNT(*) as count FROM club_registrations WHERE club_name = ?', [TEST_CLUB_NAME]);
    const dbCount = dbResult.rows[0].count;
    logger.info(`数据库中记录的报名人数: ${dbCount}`);

    // 验证Redis中的计数
    const redisCount = await cache.get(`club:${TEST_CLUB_NAME}:count`);
    logger.info(`Redis中记录的报名人数: ${redisCount}`);

    // 检查是否符合预期
    if (dbCount === TEST_CLUB_MEMBER_COUNT && redisCount === TEST_CLUB_MEMBER_COUNT) {
      logger.info('测试通过: 报名人数符合预期');
    } else {
      logger.error('测试失败: 报名人数不符合预期');
    }

    return results;
  } catch (error) {
    logger.error('运行并发测试错误:', error);
    throw error;
  }
}

// 清理测试数据
async function cleanupTestData() {
  try {
    logger.info('清理测试数据...');

    // 删除测试社团
    await query('DELETE FROM clubs WHERE club_name = ?', [TEST_CLUB_NAME]);

    // 删除测试报名记录
    await query('DELETE FROM club_registrations WHERE club_name = ?', [TEST_CLUB_NAME]);

    // 清除相关缓存
    await cache.del(`club:${TEST_CLUB_NAME}:count`);
    await cache.del(`club:${TEST_CLUB_NAME}:limit`);
    for (let i = 1; i <= TEST_STUDENT_COUNT; i++) {
      await cache.del(`student:测试学生${i}:registration`);
    }

    logger.info('测试数据清理完成');
  } catch (error) {
    logger.error('清理测试数据错误:', error);
    throw error;
  }
}

// 运行测试
async function runTest() {
  try {
    await prepareTestData();
    await runConcurrentTest();
  } catch (error) {
    logger.error('测试失败:', error);
  } finally {
    // 可选：是否清理测试数据
    // await cleanupTestData();
  }
}

// 执行测试
runTest();